<template>
    <el-form ref="searchFormRef" :model="searchForm" :rules="formRules" size="default">
        <!-- 使用了不稳定的 key，可能会导致一些不可预期的行为，比如输入框失去焦点。 -->
        <el-row>
            <el-col :xs="24" :sm="24" :md="24" :lg="item.span || 12" :xl="item.span || 12" v-for="item in formOptions"
                :key="item.vm">
                <el-form-item :label="item.props.label" :prop="item.vm" v-if="!item.isHidden">
                    <el-input v-if="item.type === FormOptionsType.INPUT" v-model.lazy.trim="searchForm[item.vm]"
                        v-bind="item.props" class="ml10 w100"></el-input>

                    <el-select v-if="item.type === FormOptionsType.SELECT" v-model.lazy="searchForm[item.vm]"
                        v-bind="item.props" class="ml10 w100" fit-input-width>
                        <!-- <el-option label="全部" value="全部"></el-option> -->
                        <el-option v-for="option in item.selectOptions" :key="option.value" :label="option.label"
                            :value="option.value" :disabled="option.disabled">
                        </el-option>
                    </el-select>

                    <el-cascader v-if="item.type === FormOptionsType.CASCADER" v-model.lazy="searchForm[item.vm]"
                        :options="item.cascaderOptions" v-bind="item.props" class="ml10 w100" :props="CustomCascaderProps"/>

                    <el-date-picker v-if="item.type === FormOptionsType.DATE_PICKER" v-model.lazy="searchForm[item.vm]"
                        v-bind="item.props" class="ml10 w100"></el-date-picker>
                    
                    <el-radio-group v-if="item.type === FormOptionsType.RADIO" v-model.lazy="searchForm[item.vm]" class="ml10 w100">
                        <el-radio v-for="option in item.selectOptions" :label="option.value">{{ option.label
                        }}</el-radio>
                    </el-radio-group>
                </el-form-item>
            </el-col>
            <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="6" class="xs-mt" v-if="showFooter">
                <el-form-item style="margin-left: 10px">
                    <el-button @click="onSearch('reset')"> 重置 </el-button>
                    <el-button type="primary" @click="onSearch()"> 查询 </el-button>
                </el-form-item>
            </el-col>
        </el-row>
    </el-form>
</template>

<script setup lang="ts" name="newForm">
import { toRefs, ref, reactive } from "vue";
import type { PropType } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import { debounce } from "src/utils/debounce";
import { watch } from "vue";
import { CustomCascaderProps } from "src/pages/clueManager/const";
const searchFormRef = ref<FormInstance>();

enum FormOptionsType {
    INPUT = "input", // 输入框
    SELECT = "select", // 下拉框
    CASCADER = "cascader", // 级联选择器
    DATE_PICKER = "date-picker", // 日期选择器
    RADIO = 'radio'
}

const props = defineProps({
    formOptions: {
        type: Array as PropType<FormOptions[]>,
        required: true
    },
    searchForm: {
        type: Object as PropType<SearchFormType>,
        required: true
    },
    showFooter: {
        type: Boolean,
        default: true
    }
});
const { formOptions, searchForm, showFooter } = toRefs(props);

const formRules = reactive<FormRules<any>>({
})

const uniqueByKey = (array: any[], key: string): any[] => {
  const seen = new Set();
  return array.filter((item) => {
    const keyValue = item[key];
    return seen.has(keyValue) ? false : seen.add(keyValue);
  });
}

// 动态生成 formRules
watch(() => formOptions, (newVal) => {
    const options = formOptions.value
    options.filter(item => item.required || item.rules).forEach(item => {
        const { vm, props, required, rules } = item
        const currentRules = []
        if (required) {
            currentRules.push({ required: true, message: props.placeholder || '该选项不能为空', trigger: 'blur' })
        }
        if (rules && rules.length) {
            currentRules.push(...rules)
        }
        // 如果都有required 则去重
        const targetRules = uniqueByKey(currentRules, 'required')
        formRules[vm] = [ ...targetRules ]
    })
}, {
    immediate: true
})

const emit = defineEmits(["search"]);
const debouncedEmitSearch = debounce((type:any) => emit("search", type));
const onSearch = (type?: string) => {
    if (type) searchFormRef.value?.resetFields();
    debouncedEmitSearch(type);
};

// onBeforeUnmount(() => searchFormRef.value?.resetFields());
const validateForm = async () => {
    return await searchFormRef.value?.validate((valid) => valid)
}
const clearCache = () => {
    searchFormRef.value?.resetFields();
}
defineExpose({ searchFormRef, clearCache, validateForm });
</script>

<style scoped lang="scss">
:deep(.el-form-item__label) {
    margin-left: 10px;
    min-width: 80px;
}
</style>
